package com.wang.springbootinit.service.impl.GenChart;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.wang.springbootinit.Listener.MQGenChartAsyncModel;
import com.wang.springbootinit.common.CommonUtils;
import com.wang.springbootinit.common.ErrorCode;
import com.wang.springbootinit.constant.ErrorMessageConstant;
import com.wang.springbootinit.constant.MQConstant;
import com.wang.springbootinit.constant.UserConstant;
import com.wang.springbootinit.exception.BusinessException;
import com.wang.springbootinit.exception.ThrowUtils;
import com.wang.springbootinit.manager.RedisLimiterManager;
import com.wang.springbootinit.mapper.SourceFileMapper;
import com.wang.springbootinit.minio.MinioUtil;
import com.wang.springbootinit.model.dto.chart.GenChartByAiRequest;
import com.wang.springbootinit.model.entity.Chart;
import com.wang.springbootinit.model.entity.User;
import com.wang.springbootinit.model.enums.ChartStatusEnum;
import com.wang.springbootinit.model.result.BIResponseResult;
import com.wang.springbootinit.model.vo.BIResponse;
import com.wang.springbootinit.service.ChartService;
import com.wang.springbootinit.service.UserService;
import com.wang.springbootinit.utils.ExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@Service
@Slf4j
public class GenChartAsyncServiceImpl {
    private static final Logger LOGGER = LoggerFactory.getLogger(GenChartAsyncServiceImpl.class);
    @Resource
    private ChartService chartService;
    @Resource
    private UserService userService;
    @Resource
    private RedisLimiterManager redisLimiterManager;
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private GenChartAfterHandler genChartAfterHandler;
    @Resource
    private RocketMQTemplate rocketMQTemplate;
    @Resource
    private MinioUtil minioUtil;
    @Resource
    private SourceFileMapper sourceFileMapper;

    public BIResponseResult genChartByAiAsync(MultipartFile multipartFile, GenChartByAiRequest genChartByAiRequest, HttpServletRequest request) {
        BIResponseResult biResponseResult = new BIResponseResult();
        String paramName = genChartByAiRequest.getName();
        String paramChartType = genChartByAiRequest.getChartType();
        String paramGoal = genChartByAiRequest.getGoal();

        //校验文件是否合法
        CommonUtils.verifyFile(multipartFile, paramName, paramChartType);

        User loginUser = userService.getLoginUser(request);
        if(loginUser.getInvokeCount() <= 0){
            throw new BusinessException(ErrorCode.NO_INVOKE_COUNT);
        }
        //对接口进行限流
        redisLimiterManager.doRateLimit(UserConstant.RateLimit + loginUser.getId());

        String excelInfo = ExcelUtils.excelToCsv(multipartFile);

        /**
         * 先将数据保存到数据库中，状态设置为 wait
         * 线程池执行智能分析 图表状态设置为running
         * 分析完成之后， 图表状态设置为succeed或failed 并将信息返回
         */

        //将生成的数据插入到数据库中
        Chart chart = new Chart();
        chart.setName(paramName);
        chart.setGoal(paramGoal);
        chart.setChartType(paramChartType);
        chart.setUserId(loginUser.getId());
        chart.setStatus(ChartStatusEnum.WAIT.getValue()); //设置为等待状态
        chart.setExecMessage(ErrorMessageConstant.CHART_NOT_GENERATED);
        chart.setChartData(excelInfo);
        ThrowUtils.throwIf(!chartService.save(chart), ErrorCode.SYSTEM_ERROR, ErrorMessageConstant.CHART_SAVE_FAILURE);

        //先上传文件
        Long sourceFileId = genChartAfterHandler.uploadGenChartFile(multipartFile, chart.getId(), loginUser.getId());
        if (ObjectUtil.isNotNull(sourceFileId)) {
            //会话消息体
            String aiHandleMessage = GenChartCommonUtil.getAiHandleMessage(paramName, paramChartType, excelInfo);
            //发送消息
            MQGenChartAsyncModel mqModel = new MQGenChartAsyncModel();
            mqModel.setContent(aiHandleMessage);
            mqModel.setUserId(loginUser.getId());
            mqModel.setSourceFileId(sourceFileId);
            mqModel.setChartId(chart.getId());
            LOGGER.info("genChartByAiAsync MQProducer message:{}", JSONUtil.toJsonStr(mqModel));
            rocketMQTemplate.convertAndSend(MQConstant.ANALYSE_TOPIC, mqModel);
        }

        //返回结果
        BIResponse biResponse = new BIResponse();
        biResponse.setChartId(chart.getId());
        biResponseResult.setData(biResponse);
        return biResponseResult;
    }

}
